#define	C_ARRIBA 1
#define	C_ABAJO  2
#define	C_IZQ    3
#define	C_DER    4

#define C_TAMANO_TILE 32

import "mod_key";
import "mod_map";
import "mod_video";
import "mod_text";
import "mod_scroll";
import "Mod_proc";
import "mod_sound";
import "Mod_screen";
import "Mod_draw";
import "Mod_grproc";
import "Mod_rand";
import "mod_file";
import "mod_math";
import "mod_say";
import "mod_debug";
import "mod_string";
import "mod_timers";

local
int width;
int height;
float xx;
float yy;

Global
n_fps;

res_x = 320;
res_y = 240;


int mapeado[7][20] = 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                     1,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,1,
					 1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,
					 1,0,0,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
					 1,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,
					 1,0,0,1,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,1,
					 1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,
					 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1;
					 
fpg_tiles;
				 
process main()
private
int i,j,fondo,x_inicial,y_inicial,num_tiles=0;
begin
set_mode(res_x,res_y,8,mode_2xscale);
set_fps(60,0);


//dibujamos mapeado
fondo = map_new(672,256,8);
fpg_tiles = load_fpg("tiles.fpg");

//Crear todos los tiles
/*for (i=0;i<8;i++)
	for (j=0;j<21;j++)
	    //mapeado[i][j] = rand(0,1);
		//if (mapeado[i][j] == 1)
			//drawing_map(0,fondo);
			//drawing_color(300);
			//draw_box((j*32),(i*32),(j*32)+32,(i*32)+32);
			//map_put(fpg_tiles,fondo,1,(j*32)+16,(i*32)+16);
			tile(mapeado[i][j],(j*32)+16,(i*32)+16,i,j);
			num_tiles++;
		//end;
	end;
end;*/

//crear solo los que se ven
for (i=(y_inicial/C_TAMANO_TILE);i<=(((res_y+y_inicial)/C_TAMANO_TILE)+1);i++)
	for (j=(x_inicial/C_TAMANO_TILE);j<=(((res_x+x_inicial)/C_TAMANO_TILE)+1);j++)
		tile(mapeado[i][j],(j*32)+16,(i*32)+16,i,j);
		num_tiles++;
	end;
end;

//arrancamos scroll
start_scroll(0,0,fondo,0,0,0);
scroll[0].camera = actor();

loop
	if (key(_f))
		set_fps(0,0);
	end;
	if (key(_p))
		set_fps(60,0);
	end;
	
	if (n_fps < 59)
		n_fps = n_fps+1;
	else
		n_fps = 0;
	end;
	frame;
end;
end;

process actor()
private 
int i,j;
int dir;
float velX,velY,friction,gravity,c_vel;
int jumping,grounded;
struct tiles_comprobar[8]
	int posx;
	int posy;
end;
BEGIN
	ctype = c_scroll;
	
	width = 32;
	height = 32;
	
	graph = map_new(width,height,8);
	drawing_map(0,graph);
	drawing_color(200);
	draw_box(0,0,width,height);
	flags = B_ABLEND;
	

	c_vel = 3.4;
	friction = 0.8;
	gravity  = 0.3;
	
	x = 64;
	y = 80;
	xx = x;
	yy = y;
	
	loop
	
		//hero controls
		if (key(_up)) 
			if(!jumping && grounded) 
				jumping = true;
				grounded = false;
				velY = -c_vel*2;
			end;
		end;
		
		if (key(_right)) 
			if (velX < c_vel) 
				velX++;
			end;
		end;
		if (key(_left)) 
			if (velX > -c_vel) 
				velX--;
			end;
		end;
		
		//physics
		velX *= friction;
		velY += gravity;
		
		//collisions
		grounded = false;
		 
		//comprobamos 9 tiles alrededor del actor
		tiles_comprobar[0].posx = x/32;
		tiles_comprobar[0].posy = y/32;
		
		tiles_comprobar[1].posx = x/32;
		tiles_comprobar[1].posy = (y/32)+1;
		
		tiles_comprobar[2].posx = x/32;
		tiles_comprobar[2].posy = (y/32)-1;
		
		tiles_comprobar[3].posx = (x/32)+1;
		tiles_comprobar[3].posy = y/32;
		
		tiles_comprobar[4].posx = (x/32)-1;
		tiles_comprobar[4].posy = y/32;
		
		tiles_comprobar[5].posx = (x/32)+1;
		tiles_comprobar[5].posy = (y/32)+1;
		
		tiles_comprobar[6].posx = (x/32)-1;
		tiles_comprobar[6].posy = (y/32)+1;
		
		tiles_comprobar[7].posx = (x/32)+1;
		tiles_comprobar[7].posy = (y/32)-1;
		
		tiles_comprobar[8].posx = (x/32)-1;
		tiles_comprobar[8].posy = (y/32)-1;
		
		for (i=0;i<9;i++)
			if (mapeado[tiles_comprobar[i].posy][tiles_comprobar[i].posx] <> 0) //si es tile solido
				dir = colCheckAABB(id,(tiles_comprobar[i].posx*32)+16,(tiles_comprobar[i].posy*32)+16,32,32);
			else
				dir = 0;
			end;
			
			if (dir == C_IZQ || dir == C_DER) 
				velX = 0;
				jumping = false;
			elseif (dir == C_ABAJO) 
				grounded = true;
				jumping = false;
			elseif (dir == C_ARRIBA) 
				velY = 0;		
				//velY *= -1;
			end;
		end;
		
		
		//update c_vels
		if (grounded)
			velY = 0;
		end;
		
		xx += velX;
		yy += velY;
		
		//escalamos la posicion de floats en enteros
		if (abs(xx-x)>=1 ) //si la diferencia entre el float y el entero es una unidad
			x = xx;
		end;
		y = yy;

		frame;
end;
end;


process caja(int x, int y)
BEGIN
	width = 32;
	height = 32;
	graph = map_new(width,height,8);
	drawing_map(0,graph);
	drawing_color(300);
	draw_box(0,0,width,height);
	xx = x;
	yy = y;
	ctype = c_scroll;
	loop
		
		frame;
	end;
end;


//Colision entre proceso y AABB
function int colCheckAABB(int shapeA, int shapeBxx,int shapeByy,int shapeBWidth,int shapeBHeight)
private
float vX,vY,hWidths,hHeights,oX,oY;
int ColDir;
begin
    // get the vectors to check against
        vX = (shapeA.xx) - (shapeBxx );
        vY = (shapeA.yy) - (shapeByy );
        // add the half widths and half heights of the objects
        hWidths = (shapeA.width / 2) + (shapeBwidth / 2);
        hHeights = (shapeA.height / 2) + (shapeBheight / 2);
        colDir = 0;

    // if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
    if (abs(vX) < hWidths && abs(vY) < hHeights) 
        // figures out on which side we are colliding (top, bottom, left, or right)
        oX = hWidths - abs(vX);
        oY = hHeights - abs(vY);
        if (oX >= oY) 
            if (vY > 0) 
				colDir = C_ARRIBA;
                shapeA.yy += oY;
             else 
                colDir = C_ABAJO;
                shapeA.yy -= oY;
             end;
        else 
            if (vX > 0) 
                colDir = C_IZQ;
                shapeA.xx += oX;
             else 
                colDir = C_DER;
                shapeA.xx -= oX;
             end;
	     end;
	end;
        
    
    return colDir;

end;

//Colision entre procesos solidos
function int colCheckProcess(int shapeA,int shapeB)
private
float vX,vY,hWidths,hHeights,oX,oY;
int ColDir;
begin
    // get the vectors to check against
        vX = (shapeA.xx) - (shapeB.xx );
        vY = (shapeA.yy) - (shapeB.yy );
        // add the half widths and half heights of the objects
        hWidths = (shapeA.width / 2) + (shapeB.width / 2);
        hHeights = (shapeA.height / 2) + (shapeB.height / 2);
        colDir = 0;

    // if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
    if (abs(vX) < hWidths && abs(vY) < hHeights) 
        // figures out on which side we are colliding (top, bottom, left, or right)
        oX = hWidths - abs(vX);
        oY = hHeights - abs(vY);
        if (oX >= oY) 
            if (vY > 0) 
				colDir = C_ARRIBA;
                shapeA.yy += oY;
             else 
                colDir = C_ABAJO;
                shapeA.yy -= oY;
             end;
        else 
            if (vX > 0) 
                colDir = C_IZQ;
                shapeA.xx += oX;
             else 
                colDir = C_DER;
                shapeA.xx -= oX;
             end;
	     end;
	end;
        
    
    return colDir;

end;

process tile(graph,x,y,posi,posj)
private
int i_frame = 1;//incremento de frame de animacion
int t_frame = 0;//tiempo de frame de animacion
int capa; //id del proceso de la segunda capa
begin
priority=-99;
file=fpg_tiles;
ctype=c_scroll;
z=1;
loop
	
		
	//Si sale el tile por la izquierda
	if (scroll[0].x0-(x+(C_TAMANO_TILE/2))>=C_TAMANO_TILE) 
 	   	graph=mapeado[posi][(posj+(res_x/C_TAMANO_TILE))+2];
	 	x=x+(res_x+(C_TAMANO_TILE*2));
		y=y;                               
		posi=posi;
		posj=posj+(res_x/C_TAMANO_TILE)+2;
	end;
		
	//Si sale el tile por la derecha
	if ((x-(C_TAMANO_TILE/2))-scroll[0].x0>((res_x+C_TAMANO_TILE)-(C_TAMANO_TILE))
	    && (x-(C_TAMANO_TILE/2))-scroll[0].x0<((res_x+C_TAMANO_TILE)+(C_TAMANO_TILE))
	    ) 
		graph=mapeado[posi][(posj-(res_x/C_TAMANO_TILE)-2)];
		x=x-(res_x+(C_TAMANO_TILE*2));
		y=y;
		posi=posi;
		posj=posj-(res_x/C_TAMANO_TILE)-2;
	end;
	
	//Si sale por arriba
	if (scroll[0].y0-(y)>=C_TAMANO_TILE) 
 		graph=mapeado[posi+(res_y/C_TAMANO_TILE)+2][posj];
		x=x;
		y=y+(res_y+(C_TAMANO_TILE*2))-(C_TAMANO_TILE/2);
		posi=posi+(res_y/C_TAMANO_TILE)+2;
		posj=posj;       
	end;
	
	//Si sale por abajo
	if ((y-(C_TAMANO_TILE/2))-scroll[0].y0>((res_y+C_TAMANO_TILE-(C_TAMANO_TILE/2))-(C_TAMANO_TILE/2))
	    && (y-(C_TAMANO_TILE/2))-scroll[0].y0<((res_y+C_TAMANO_TILE-(C_TAMANO_TILE/2))+(C_TAMANO_TILE/2))
	    )
		graph=mapeado[posi-(res_y/C_TAMANO_TILE)-2][posj];
		x=x;
		y=y-(res_y+(C_TAMANO_TILE))-(C_TAMANO_TILE/2);
		posi=posi-(res_y/C_TAMANO_TILE)-2;
		posj=posj;       
	end;
	
	
	frame;
end;
end;